#include "widget.h"
#include "ui_widget.h"
#include<QDataStream>
#include<QMessageBox>
#include<QDateTime>
#include<QColorDialog>
#include<QFileDialog>
#include<QFile>
#include<QTextStream>
Widget::Widget(QWidget *parent,QString name) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    //初始化操作
    udp=new QUdpSocket;
    //端口号初始化
    this->port=9999;
    //用户名
    uName=name;
    //绑定端口号  参数1：端口号  参数2：共享地址以及重新连接服务器
    udp->bind(this->port,QUdpSocket::ShareAddress|QUdpSocket::ReuseAddressHint);
    //发送新用户进入
    sendMsg(UserEnter);
    //点击发送按钮发送消息
    connect(ui->sendBtn,&QPushButton::clicked,[=](){
        //发送普通消息
        sendMsg(Msg);
    });

    //监听别人发送的数据
    connect(udp,&QUdpSocket::readyRead,this,&Widget::ReceiveMsg);
    //退出按钮退出
    connect(ui->exitBtn,&QPushButton::clicked,[=](){
        this->close();
    });

    ////////辅助功能///////////
    //字体
    connect(ui->fontCbx,&QFontComboBox::currentFontChanged,[=](const QFont &font){
       ui->msgTxtedit->setCurrentFont(font);
       ui->msgTxtedit->setFocus();
    });
    //字号
    void(QComboBox::*cbxsignals)(const QString &text)=&QComboBox::currentIndexChanged;
    connect(ui->sizeCbx,cbxsignals,[=](const QString &text){
        ui->msgTxtedit->setFontPointSize(text.toDouble());
        ui->msgTxtedit->setFocus();
    });
    //加粗
    connect(ui->boldBtn,&QToolButton::clicked,[=](bool isCheck){
        if(isCheck)
        {
            ui->msgTxtedit->setFontWeight(QFont::Bold);
        }
        else {
            ui->msgTxtedit->setFontWeight(QFont::Normal);
        }
    });
    //倾斜
    connect(ui->italicBtn,&QToolButton::clicked,[=](bool check){
        ui->msgTxtedit->setFontItalic(check);
    });
    //下划线
    connect(ui->underlineBtn,&QToolButton::clicked,[=](bool check){
        ui->msgTxtedit->setFontUnderline(check);
    });
    //字体颜色
    connect(ui->colorBtn,&QToolButton::clicked,[=](){
        QColor color=QColorDialog::getColor(Qt::red);
        ui->msgTxtedit->setTextColor(color);
    });
    //清空聊天记录
    connect(ui->clearBtn,&QToolButton::clicked,[=](){
        ui->msgBrowser->clear();
    });
    //保存文件
    connect(ui->saveBtn,&QToolButton::clicked,[=](){
       if(ui->msgBrowser->document()->isEmpty())
       {
           QMessageBox::warning(this,"警告","聊天记录不能为空!");
           return;
       }
       QString path=QFileDialog::getSaveFileName(this,"保存文件","聊天记录","(*.txt)");
       if(path.isEmpty())
       {
           QMessageBox::warning(this,"警告","文件路径不能为空");
           return;
       }
       else {
           QFile file(path);
           //打开模式加换行
           file.open(QIODevice::WriteOnly|QIODevice::Text);
           QTextStream stream(&file);
           //以纯文本的方式写入txt中
           stream<<ui->msgBrowser->toPlainText();
           file.close();
       }
    });

}

void Widget::ReceiveMsg()
{
    //拿到报文
    //获取长度
    qint64 size=udp->pendingDatagramSize();
    QByteArray array=QByteArray(size,0);
    udp->readDatagram(array.data(),size);
    //解析报文
    //第一段类型 第二段用户名  第三段具体内容
    QDataStream stream(&array,QIODevice::ReadOnly);
    int msgType;
    QString userName;
    QString msg;
    QString time=QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss");

    stream>>msgType;//读取内容类型
    switch (msgType) {
    case Msg:
        stream>>userName>>msg;
        //显示聊天数据
        ui->msgBrowser->setTextColor(Qt::blue);
        //追加聊天格式
        ui->msgBrowser->append("["+userName+"]"+time);
        //显示聊天内容
        ui->msgBrowser->append(msg);
        break;
    case UserEnter:
        stream>>userName;
        userEnter(userName);
        break;
    case UserLeft:
        stream>>userName;
        userLeft(userName,time);
        break;
    default:
        break;
    }

}

void Widget::userLeft(QString username,QString time)
{
    bool isempty=ui->userTalWidget->findItems(username,Qt::MatchExactly).isEmpty();
    if(!isempty)
    {
        //找到将被移除的行
        int row=ui->userTalWidget->findItems(username,Qt::MatchExactly).first()->row();
        //移除某行
        ui->userTalWidget->removeRow(row);
        //追加到聊天记录
        ui->msgBrowser->setTextColor(Qt::gray);
        ui->msgBrowser->append(QString("%1 于 %2离开").arg(username).arg(time));
        //在线人数更新
        ui->userNumLabel->setText(QString("在线用户: %1人").arg(ui->userTalWidget->rowCount()));
    }
}

void Widget::userEnter(QString username)
{
    bool isempty=ui->userTalWidget->findItems(username,Qt::MatchExactly).isEmpty();
    if(isempty)
    {
        QTableWidgetItem*user=new QTableWidgetItem(username);
        //插入行
        ui->userTalWidget->insertRow(0);
        ui->userTalWidget->setItem(0,0,user);
        //追加到聊天记录中
        ui->msgBrowser->setTextColor(Qt::gray);
        ui->msgBrowser->append(QString("%1 上线了").arg(username));
        //在线人数更新
        ui->userNumLabel->setText(QString("在线用户: %1人").arg(ui->userTalWidget->rowCount()));
        //把自身信息广播出去
        sendMsg(UserEnter);
    }
}

void Widget::sendMsg(MsgType type)
{
    //发送消息分为三种类型
    //发送的数据做分段处理   第一段内容是类型  第二段是用户名  第三段是具体内容
    QByteArray array;
    QDataStream stream(&array,QIODevice::WriteOnly);
    stream<<type<<getuserName();
    switch (type) {
        case Msg:              //普通消息
            if(ui->msgTxtedit->toPlainText()=="")
            {
            QMessageBox::warning(this,"警告","发送内容不能为空");
            return;
            }
        //第二段内容具体发送的消息
            stream<<getMsg();
            break;
        case UserEnter:        //用户进入消息
            break;
        case UserLeft:         //用户离开消息
            break;
    }
    //书写报文   以广播的形式发送ip（255.255.255.255）
    udp->writeDatagram(array,QHostAddress::Broadcast,port);

}

QString Widget::getuserName()
{
    return this->uName;
}

QString Widget::getMsg()
{
    QString str=ui->msgTxtedit->toHtml();
    //清空输入框
    ui->msgTxtedit->clear();
    //重新获取光标的焦点
    ui->msgTxtedit->setFocus();
    //返回消息
    return str;
}

//关闭窗口的事件
void Widget::closeEvent(QCloseEvent*)
{
    emit this->closeWidget();
    //发送用户离开
    sendMsg(UserLeft);
    //关闭套接字
    udp->close();
    udp->destroyed();

}

Widget::~Widget()
{
    delete ui;
}
